/*
 * Copyright (c) 2009. Silenus Consultoria, S.L.
 */
package com.tonbeller.jpivot.tags;

import com.tonbeller.jpivot.mondrian.MondrianModel;

import com.tonbeller.jpivot.olap.model.OlapException;
import com.tonbeller.jpivot.olap.model.OlapModel;

import com.tonbeller.jpivot.tags.MondrianModelFactory.Config;

import com.tonbeller.tbutils.res.Resources;

import com.tonbeller.wcf.controller.RequestContext;

import org.xml.sax.SAXException;

import java.io.IOException;

import java.net.URL;

import javax.servlet.jsp.JspException;


/**
 * jsp tag that defines a mondrian query
 */
public class MondrianOlapModelTag extends OlapModelTag {
	String dataSource;
	String jdbcDriver;
	String jdbcUser;
	String jdbcPassword;
	String jdbcUrl;
	String catalogUri;
	String config;
	String role;
	String dynResolver;
	String dynLocale;
	String connectionPooling;
	String dataSourceChangeListener;
	boolean useContentChecksum;
	Resources res = Resources.instance();

	/**
	 * Retrieves the OLAP model.
	 *
	 * @param context the request context.
	 *
	 * @return the OLAP model.
	 *
	 * @throws JspException if something goes wrong.
	 * @throws OlapException if something goes wrong.
	 * @throws SAXException if something goes wrong.
	 * @throws IOException if something goes wrong.
	 */
	protected OlapModel getOlapModel(RequestContext context)
		throws JspException, OlapException, SAXException, IOException {
		Config cfg = new Config();

		// See http://jira.pentaho.org/browse/BISERVER-275
		String schemaUrl;

		if(catalogUri.startsWith("/")) {
			schemaUrl = pageContext.getServletContext().getResource(catalogUri).toExternalForm();
		} else {
			schemaUrl = catalogUri;
		}

		cfg.setMdxQuery(getBodyContent().getString());
		// Add the schema URL.  Enclose the value in quotes to permit
		// schema URLs that include things like ;jsessionid values.
		cfg.setSchemaUrl("\"" + schemaUrl + "\"");
		cfg.setJdbcUrl(jdbcUrl);
		cfg.setJdbcDriver(jdbcDriver);
		cfg.setJdbcUser(jdbcUser);
		cfg.setJdbcPassword(jdbcPassword);
		cfg.setDataSource(dataSource);
		cfg.setRole(role);
		cfg.setDynResolver(dynResolver);
		cfg.setDynLocale(dynLocale);
		cfg.setConnectionPooling(connectionPooling);
		cfg.setDataSourceChangeListener(dataSourceChangeListener);
		// FIX: use content checksum
		cfg.setUseContentChecksum(useContentChecksum);

		allowOverride(context, cfg);

		URL url;

		if(config == null) {
			url = getDefaultConfig();
		} else {
			url = pageContext.getServletContext().getResource(config);
		}

		MondrianModel mm = MondrianModelFactory.instance(url, cfg);
		OlapModel om = (OlapModel)mm.getTopDecorator();

		om.setLocale(context.getLocale());
		om.setServletContext(context.getSession().getServletContext());

		return om;
	}

	/**
	 * default implementation delegates to {@link
	 * com.tonbeller.jpivot.tags.MondrianModelFactory.Config#allowOverride(com.tonbeller.wcf.controller.RequestContext)}
	 *
	 * @param context the request context.
	 * @param cfg the configuration.
	 */
	protected void allowOverride(RequestContext context, Config cfg) {
		cfg.allowOverride(context);
	}

	/**
	 * Retrieves the default configuration URL.
	 *
	 * @return the default configuration URL.
	 */
	protected URL getDefaultConfig() {
		return MondrianOlapModelTag.class.getResource("/com/tonbeller/jpivot/mondrian/config.xml");
	}

	/**
	 * Returns the catalogUri.
	 *
	 * @return String
	 */
	public String getCatalogUri() {
		return catalogUri;
	}

	/**
	 * Returns the jdbcDriver.
	 *
	 * @return String
	 */
	public String getJdbcDriver() {
		return jdbcDriver;
	}

	/**
	 * Returns the jdbcUrl.
	 *
	 * @return String
	 */
	public String getJdbcUrl() {
		return jdbcUrl;
	}

	/**
	 * Sets the catalogUri.
	 *
	 * @param catalogUri The catalogUri to set
	 */
	public void setCatalogUri(String catalogUri) {
		this.catalogUri = catalogUri;
	}

	/**
	 * Sets the jdbcDriver.
	 *
	 * @param jdbcDriver The jdbcDriver to set
	 */
	public void setJdbcDriver(String jdbcDriver) {
		this.jdbcDriver = jdbcDriver;
	}

	/**
	 * Sets the jdbcUrl.
	 *
	 * @param jdbcUrl The jdbcUrl to set
	 */
	public void setJdbcUrl(String jdbcUrl) {
		this.jdbcUrl = jdbcUrl;
	}

	/**
	 * Returns the jdbcPassword.
	 *
	 * @return String
	 */
	public String getJdbcPassword() {
		return jdbcPassword;
	}

	/**
	 * Returns the jdbcUser.
	 *
	 * @return String
	 */
	public String getJdbcUser() {
		return jdbcUser;
	}

	/**
	 * Sets the jdbcPassword.
	 *
	 * @param jdbcPassword The jdbcPassword to set
	 */
	public void setJdbcPassword(String jdbcPassword) {
		this.jdbcPassword = jdbcPassword;
	}

	/**
	 * Sets the jdbcUser.
	 *
	 * @param jdbcUser The jdbcUser to set
	 */
	public void setJdbcUser(String jdbcUser) {
		this.jdbcUser = jdbcUser;
	}

	/**
	 * Returns the config.
	 *
	 * @return String
	 */
	public String getConfig() {
		return config;
	}

	/**
	 * Sets the config.
	 *
	 * @param config The config to set
	 */
	public void setConfig(String config) {
		this.config = config;
	}

	/**
	 * Sets the data source.
	 *
	 * @param string the data source.
	 */
	public void setDataSource(String string) {
		dataSource = string;
	}

	/**
	 * Sets the role.
	 *
	 * @param role The role to set.
	 */
	public void setRole(String role) {
		this.role = role;
	}

	/**
	 * Retrieves the dynamic resolver.
	 *
	 * @return the dynamic variable resolver class name
	 */
	public String getDynResolver() {
		return dynResolver;
	}

	/**
	 * Sets the dynamic resolver.
	 *
	 * @param dynResolver - the dynamic variable resolver class name
	 */
	public void setDynResolver(String dynResolver) {
		this.dynResolver = dynResolver;
	}

	/**
	 * Turns on connection pooling.
	 *
	 * @param connectionPooling - "false" : Mondrian must not pool JDBC connections
	 */
	public void setConnectionPooling(String connectionPooling) {
		this.connectionPooling = connectionPooling;
	}

	/**
	 * Retrieves the connection pooling setting.
	 *
	 * @return "false" if Mondrion must not pool JDBC connections
	 */
	public String getConnectionPooling() {
		return connectionPooling;
	}

	/**
	 * Retrieves the data source.
	 *
	 * @return the data source.
	 */
	public String getDataSource() {
		return dataSource;
	}

	/**
	 * Retrieves the role.
	 *
	 * @return the role.
	 */
	public String getRole() {
		return role;
	}

	/**
	 * Getter for property locale.
	 *
	 * @return Value of property locale.
	 */
	public String getDynLocale() {
		return this.dynLocale;
	}

	/**
	 * Setter for property locale.
	 *
	 * @param dynLocale New value of property locale.
	 */
	public void setDynLocale(String dynLocale) {
		this.dynLocale = dynLocale;
	}

	/**
	 * Retrieves the data source change listener.
	 *
	 * @return Returns the data source change listener.
	 */
	public String getDataSourceChangeListener() {
		return dataSourceChangeListener;
	}

	/**
	 * DOCUMENT ME!
	 *
	 * @param dataSourceChangeListener The dataSourceChangeListener to set.
	 */
	public void setDataSourceChangeListener(String dataSourceChangeListener) {
		this.dataSourceChangeListener = dataSourceChangeListener;
	}

	// FIX: use content checksum
	/**
	 * Retrieves the content checksum flag.
	 *
	 * @return the content checksum flag.
	 */
	public boolean isUseContentChecksum() {
		return useContentChecksum;
	}

	/**
	 * Sets the content checksum flag.
	 *
	 * @param useContentChecksum the content checksum flag.
	 */
	public void setUseContentChecksum(boolean useContentChecksum) {
		this.useContentChecksum = useContentChecksum;
	}
}
